<template>
  <view class="wrap">
    <!-- 未绑定 -->
    <view class="not-bind">
      <view class="equipment-box">
        <view class="equipment-unbind" v-if="deviceNo" @tap="unbindDevice">
          <text class="unbind-text">解绑设备</text>
        </view>
        <image
          class="equipment-image"
          src="https://ainengli.hzjrsw.com/jkhx/weight/viva-icon.png"
          mode="scaleToFill"
        />
        <text class="bing-sn" v-if="connected">sn:{{ sn }}</text>
      </view>
      <view v-if="!connected">
        <!-- 蓝牙没有打开 -->
        <view v-if="!blueState">
          <view class="equipment-title" style="flex-direction: column; justify-content: center">
            <view style="display: flex; justify-content: center">
              <text class="equipment-text">请打开蓝牙，并尝试重新连接</text>
            </view>
            <view class="matching-box">
              <text class="matching-item" @tap="noBind">暂不绑定</text>
              <text class="matching-item" @tap="reuseConnect">重新连接</text>
            </view>
          </view>
        </view>
        <view v-else>
          <view v-if="deviceNo">
            <view class="equipment-title" style="flex-direction: column; justify-content: center">
              <view style="display: flex; justify-content: center">
                <text class="equipment-text">设备连接中</text>
                <up-loading-icon />
              </view>
              <text style="margin-top: 16rpx; font-size: 30rpx; color: #666; text-align: center"
                >若长时间未连接，尝试点击设备按钮开机</text
              >
            </view>

            <view class="manual-box">
              <text class="patient-confirm" @tap="manualEnter">手动录入</text>
            </view>
          </view>
          <view v-else>
            <view class="equipment-title">
              <text class="equipment-text">请选择设备</text>
              <up-loading-icon />
            </view>
            <view class="equiment-list">
              <scroll-view class="equiment-scroll" scroll-y>
                <view
                  class="device_item"
                  v-for="(item, index) in gloableDevices"
                  :key="index"
                  @tap="connectedChange(item)"
                >
                  <text class="device_name">{{ item.name || item.localName }}</text>
                </view>
              </scroll-view>
            </view>
          </view>
        </view>
      </view>
      <view v-else>
        <!-- 就诊人选择 -->
        <view class="patient-box">
          <view class="patient-title">
            <text class="bind-desc">{{ clval }}</text>
          </view>
          <view class="patient-item" v-if="!isSaveMeasureUser">
            <text class="patient-name">选择测量用户</text>
            <view class="patient-right" @tap="showSelectPatient">
              <text class="patient-value">{{ measureUserInfo }}</text>
              <image
                class="patient-select-image"
                src="https://ainengli.hzjrsw.com/jkhx/common/form-arrow-right.png"
                mode="scaleToFill"
              />
            </view>
          </view>
          <view class="patient-item" v-else>
            <text class="patient-name">测量人</text>
            <view class="patient-right">
              <text class="patient-value">{{ measureUserInfo }}</text>
            </view>
          </view>
          <!-- 测量人列表 -->
          <up-popup
            :show="isSelectPatientVisible"
            :round="16"
            mode="bottom"
            closeable
            @close="isSelectPatientVisible = false"
          >
            <view class="title">请选择测量用户</view>
            <view class="lists">
              <view
                v-for="(item, index) in familyList"
                :key="index"
                :class="['item', familyIndex == index ? 'item-active' : '']"
                @tap="selectPatientHandle(item, index)"
              >
                <text class="name">{{ item.patName }}</text>
                <view class="exam-info">
                  <text class="text">{{ item.gender }} | {{ item.age }}岁</text>
                </view>
                <image
                  v-if="familyIndex == index"
                  class="select_img"
                  src="https://ainengli.hzjrsw.com/jkhx/common/select.png"
                />
              </view>
            </view>
          </up-popup>
        </view>
      </view>
    </view>

    <view class="confirm-box" v-if="connected && !isSaveMeasureUser" @tap="saveMeasureUser">
      <text class="patient-confirm">确定</text>
    </view>
  </view>
</template>
<script setup lang="ts">
import { onMounted, ref } from 'vue'
import { onLoad, onShow, onUnload } from '@dcloudio/uni-app'
import { query_patient } from '@/api/family'
import { bindEquipment, unbindEquipment } from './equipment.api'
import { throttle } from '@/utils/tools'

interface deviceData {
  name: string
  deviceId: string
  localName: string
  mac: string
}

// 定义响应式数据
const devices = ref([])
const connected = ref(false)
const equipmentId: any = ref()
const serviceId = ref('')
const characteristicId = ref('')
const callbackres = ref('')
const clval = ref('设备已连接，选择测量人')
const measureData = ref()
const historydata = ref([])
const oper = ref('')
const sn = ref('')
let bleData = ''
let currUnit = ''
let currSn = ''
let defaultData, pmt, controlSolution, now, history

const _discoveryStarted = ref<boolean>(false)
const gloableDevices = ref<deviceData[]>([])

const wero = ref<number>(0)
const userInfo = ref()
const measureUserInfo = ref()
const measureEmpi = ref('')
const isSaveMeasureUser = ref(false)
const blueState = ref(false)
const isSelectPatientVisible = ref<boolean>(false)
const familyList = ref([])
const familyIndex = ref<number>(0)

const deviceNo = ref('')

onShow(() => {
  if (uni.hideHomeButton) {
    uni.hideHomeButton()
  }

  measureUserInfo.value =
    userInfo.value.patName + ' ' + userInfo.value.gender + ' ' + userInfo.value.age + '岁'
  measureEmpi.value = userInfo.value.empi
  getPatInfos()

  openBluetoothAdapter()
})

const getPatInfos = () => {
  query_patient(JSON.parse(uni.getStorageSync('userInfo')).userId).then((res: any) => {
    familyList.value = res.data

    familyIndex.value = res.data.findIndex((item: any) => {
      return item.empi == measureEmpi.value
    })
  })
}

const selectPatientHandle = (data: any, index: number) => {
  familyIndex.value = index
  measureUserInfo.value = data.patName + ' ' + data.gender + ' ' + data.age + '岁'
  measureEmpi.value = data.empi
  isSelectPatientVisible.value = false
  console.log(measureEmpi.value)
}
// 确定测量人
const saveMeasureUser = () => {
  isSaveMeasureUser.value = true
  clval.value = '设备已连接，等待插入试纸'
}

onLoad((e: any) => {
  uni.setNavigationBarTitle({
    title: e && e.name == 'analysis' ? '微策三合一分析仪' : ''
  })

  userInfo.value = JSON.parse(uni.getStorageSync('userInfo')).patientInfo
  deviceNo.value = e.deviceNo
  connected.value = false
  isSaveMeasureUser.value = false
})

onMounted(() => {
  // 注册蓝牙特征值变化监听器
  wx.onBLECharacteristicValueChange(callback)

  wx.onBLEConnectionStateChange(stateChange)
})

const stateChange = (res: any) => {
  if (!res.connected && connected.value) {
    uni.showToast({
      title: '蓝牙已断开',
      duration: 800
    })

    connected.value = false
    wx.closeBluetoothAdapter()
    wx.stopBluetoothDevicesDiscovery()
    wx.offBLEConnectionStateChange(stateChange)
    if (equipmentId.value) {
      wx.closeBLEConnection({
        deviceId: equipmentId.value
      })
    }

    setTimeout(() => {
      uni.redirectTo({
        url: '/module/src/pages/myEquipment/index'
      })
    }, 1000)
  }
}

// 解绑
const unbindDevice = () => {
  uni.showModal({
    title: '解除绑定',
    cancelColor: '#666',
    confirmColor: '#00D1B6',
    content: '确定要解除绑定微策三合一分析仪吗?',
    success: (res) => {
      if (res.confirm) {
        unbindEquipment(deviceNo.value).then(() => {
          wx.offBLEConnectionStateChange(stateChange)
          uni.showToast({
            title: '解绑成功',
            duration: 800
          })

          setTimeout(() => {
            uni.redirectTo({
              url: '/module/src/pages/myEquipment/index'
            })
          }, 1000)
        })
      } else if (res.cancel) {
        console.log('用户点击取消')
      }
    }
  })
}

const callback = (res: any) => {
  if (ab2hex(res.value) == callbackres.value) {
    return
  } else {
    callbackres.value = ab2hex(res.value)
    console.log('蓝牙返回2* ', ab2hex(res.value))

    bluetoothanalytics(ab2hex(res.value))
    // 更新其他数据
    sn.value = currSn
  }
}

// 显示测量人选择弹框
const showSelectPatient = () => {
  isSelectPatientVisible.value = true
}

onUnload(() => {
  console.log('销毁蓝牙模块')
  wx.closeBluetoothAdapter()
  wx.stopBluetoothDevicesDiscovery()
  wx.offBLEConnectionStateChange(stateChange)
  if (equipmentId.value) {
    wx.closeBLEConnection({
      deviceId: equipmentId.value
    })
  }

  connected.value = false
})

const openBluetoothAdapter = () => {
  console.log('初始化蓝牙模块')
  blueState.value = false
  wx.openBluetoothAdapter({
    success: () => {
      blueState.value = true
      console.log('打开蓝牙模块成功')
      if (deviceNo.value) {
        connectedHandle({ deviceId: deviceNo.value })
      } else {
        startBluetoothDevicesDiscovery()
      }
    },
    fail: (res: any) => {
      console.log(res)
      if (res.errCode == undefined) {
        blueState.value = true
        wx.showToast({
          title: '该设备不支持蓝牙',
          duration: 1000
        })
      }
      if (res.errCode === 10001) {
        blueState.value = false
        wx.showToast({
          title: '请开启蓝牙',
          duration: 1000
        })
      }
    }
  })
}

// 手动录入  -- 跳转至健康监测
const manualEnter = () => {
  uni.redirectTo({
    url: '/module/src/pages/healthPortrait/indexTwo'
  })
}

// 蓝牙打开重新连接
const reuseConnect = () => {
  openBluetoothAdapter()
}

const noBind = () => {
  uni.redirectTo({
    url: '/module/src/pages/myEquipment/index'
  })
}

const startBluetoothDevicesDiscovery = () => {
  if (_discoveryStarted.value) {
    return
  }
  console.log('搜寻附近的蓝牙设备')
  _discoveryStarted.value = true
  wx.startBluetoothDevicesDiscovery({
    allowDuplicatesKey: false, //拒绝重复
    //services: ['6958'],
    success: () => {
      console.log('搜索设备成功')
      onBluetoothDeviceFound()
    },
    fail: () => {
      console.log('搜索设备失败,请重试')
    }
  })
}

const onBluetoothDeviceFound = () => {
  //监听设备
  // gloableDevices.value = []
  wx.onBluetoothDeviceFound((res: any) => {
    res.devices.forEach((device: any) => {
      if (!device.name && !device.localName) {
        return
      }
      // const foundDevices: any = []
      // const idx = inArray(foundDevices, 'deviceId', device.deviceId)
      const idx = gloableDevices.value.findIndex((v) => {
        return v.deviceId === device.deviceId
      })
      const data: any = {}

      //添加mac数据
      console.log(ab2hex(devices.value.advertisData))
      device.mac = ab2hex(device.advertisData)
        .substring(4)
        .replace(/(\w{2})(?=\w{2,}$)/g, '$1:')

      const macIdx = gloableDevices.value.findIndex((v) => {
        return v.mac === device.mac
      })

      if (idx === -1 && macIdx === -1) {
        gloableDevices.value.push(device)
      } else if (idx > -1) {
        gloableDevices.value[idx] = device
      } else if (macIdx > -1) {
        gloableDevices.value[macIdx] = device
      }
    })
    console.log(gloableDevices.value)
  })
}

// 点击设备链接
const connectedChange = throttle((e: any) => {
  uni.showLoading()
  if (e.name == 'BLE_VivaChek') {
    connectedHandle(e)
  } else {
    uni.hideLoading()
    uni.showToast({
      title: '暂不支持该设备',
      icon: 'none'
    })
  }
}, 300)
// 链接设备
const connectedHandle = (e: any) => {
  const deviceId = e.deviceId
  console.log(e)
  if (deviceId) {
    createBLEConnection(deviceId)
  } else {
    uni.hideLoading()
    uni.showToast({
      title: '暂不支持该设备',
      icon: 'none'
    })
  }
}

const createBLEConnection = (deviceId: string) => {
  wx.createBLEConnection({
    deviceId,
    success: (res: any) => {
      uni.hideLoading()
      console.log('连接设备成功')
      wx.showToast({
        title: '连接设备成功',
        duration: 500
      })
      equipmentId.value = deviceId
      getBLEDeviceServices(equipmentId.value) //获取服务
      connected.value = true
    },
    fail: (res) => {
      uni.hideLoading()
      connected.value = false
      // wx.showToast({
      //   title: '连接设备失败，请重试',
      //   duration: 1000
      // })

      // setTimeout(() => {
      //   uni.redirectTo({
      //     url: '/module/src/pages/myEquipment/index'
      //   })
      // }, 1000)
    }
  })

  wx.stopBluetoothDevicesDiscovery() //停止搜索设备
}

//获取服务
const getBLEDeviceServices = (deviceId) => {
  // console.log('开始获取服务');
  wx.getBLEDeviceServices({
    deviceId,
    success: (res) => {
      // console.log('获取服务: ' + JSON.stringify(res));
      for (let i = 0; i < res.services.length; i++) {
        if (res.services[i].isPrimary) {
          console.log('服务' + i + '：' + JSON.stringify(res.services[i].uuid))
          // this.getBLEDeviceCharacteristics(deviceId, res.services[i].uuid)
          // return
        }
      }
      getBLEDeviceCharacteristics(deviceId)
    },
    fail: (res) => {
      console.log('获取服务失败')
    }
  })
}

const getBLEDeviceCharacteristics = (deviceId) => {
  //获取特征
  // console.log('开始获取特征');
  wx.getBLEDeviceCharacteristics({
    deviceId,
    serviceId: '0003CDD0-0000-1000-8000-00805F9B0131',
    success: (res) => {
      for (let i = 0; i < res.characteristics.length; i++) {
        const item = res.characteristics[i]
        console.log('特征' + JSON.stringify(item))
      }

      wx.notifyBLECharacteristicValueChange({
        deviceId,
        serviceId: '0003CDD0-0000-1000-8000-00805F9B0131',
        characteristicId: '0003CDD1-0000-1000-8000-00805F9B0131',
        state: true,
        success: (res) => {
          console.log('开启订阅模式')

          if (wero.value == 1) {
            wx.showToast({
              title: '请重新操作',
              duration: 1000
            })
          }
          getNow()
        },
        fail: (res) => {
          console.log('开启订阅失败')
        }
      })
    },
    fail(res) {
      console.log('获取特征失败')
    }
  })
}

// 开始实时获取数据
const getNow = () => {
  console.log('实时测量')
  oper.value = 'now'
  now = true
  clval.value = '设备连接成功'
  writeBLECharacteristicValue()
}

const writeBLECharacteristicValue = () => {
  // 向蓝牙设备发送一个0x00的16进制数据
  let buffer = new ArrayBuffer(1)
  var buf = '7b0110012077550000010b0b047d'
  buffer = string2buffer(buf)

  console.log('deviceId:', equipmentId.value)
  console.log('buffer:', buffer)
  console.log('buffer:', ab2hex(buffer))

  wx.writeBLECharacteristicValue({
    deviceId: equipmentId.value,
    serviceId: '0003CDD0-0000-1000-8000-00805F9B0131', //服务id 可以写死
    characteristicId: '0003CDD2-0000-1000-8000-00805F9B0131', //监控特征值id

    value: buffer,
    success: (res) => {
      console.log('写入数据成功')
      wero.value = 0
    },
    fail: (res) => {
      console.log('写入数据失败')
      console.log(res)

      wero.value = 1

      getBLEDeviceCharacteristics(equipmentId.value)
    }
  })
}

// ArrayBuffer转16进度字符串
const ab2hex = (buffer: any) => {
  const hexArr = Array.prototype.map.call(new Uint8Array(buffer), function (bit) {
    return ('00' + bit.toString(16)).slice(-2)
  })
  return hexArr.join('')
}

// 转为ArrayBuffer
const string2buffer = (str: any) => {
  // 将16进制转化为ArrayBuffer
  return new Uint8Array(
    str.match(/[\da-f]{2}/gi).map(function (h) {
      return parseInt(h, 16)
    })
  ).buffer
}

const bluetoothanalytics = (a) => {
  /**
   * 上次测量结果的状态
   **/
  const LAST_TIME_MEASURE_STATE_PRE = '7b012001101266000510'

  /**
   * 插入试纸条
   * 11：血糖
   * 66：血酮
   * aa：尿酸
   **/
  const INSERT_GLU_SENSOR_PRE = '7b012001101266000511'
  const INSERT_KET_SENSOR_PRE = '7b012001101266000566'
  const INSERT_UA_SENSOR_PRE = '7b0120011012660005aa'

  /**
   * 等待加血
   * 22：血糖
   * 77：血酮
   * bb：尿酸
   **/
  const WAITING_TO_ADD_BLOOD_GLU_PRE = '7b012001101266000522'
  const WAITING_TO_ADD_BLOOD_KET_PRE = '7b012001101266000577'
  const WAITING_TO_ADD_BLOOD_UA_PRE = '7b0120011012660005bb'

  /**
   * 已加血
   * 33：血糖
   * 88：血酮
   * cc：尿酸
   **/
  const COMPLETED_TO_ADD_BLOOD_GLU_PRE = '7b012001101266000533'
  const COMPLETED_TO_ADD_BLOOD_KET_PRE = '7b012001101266000588'
  const COMPLETED_TO_ADD_BLOOD_UA_PRE = '7b0120011012660005cc'

  /**
   * 测量结果
   * 44：血糖
   * 99：血酮
   * dd：尿酸
   **/
  const MEASURE_RESULT_VALUE_GLU_PRE = '7b012001101266000544'
  const MEASURE_RESULT_VALUE_KET_PRE = '7b012001101266000599'
  const MEASURE_RESULT_VALUE_UA_PRE = '7b0120011012660005dd'

  /**
   * 测量结果(时间值)
   **/
  const MEASURE_RESULT_TIME_PRE = '7b0120011044aa0006'

  /**
   * 测量异常报警
   **/
  const ERROR_ALARM_PRE = '7b012001101266000555'

  /**
   * 设备S/N串号
   **/
  const SN_PRE = '7b0120011077aa'

  /**
   * 设备的测量单位
   **/
  const UNIT_PRE = '7b01200110aaaa0001'

  /**
   * 历史数据
   **/
  const HISTORY_PRE = '7b01200110ddaa0009'

  /**
   * 历史数据结束
   **/
  const HISTORY_END_PRE = '7b01200110d166'

  /**
   * 设备关机
   **/
  const POWER_OFF = '7b01200110d26600000b0907007d'

  /**
   * 同步设置设备时间成功
   **/
  const SET_TIME_SUCCESS = '7b012001104499000111000802077d'

  const END_7D = '7d'

  /**
   * 设备单位为：mmol/L
   **/
  const MMOL = 'mmol/L'

  /**
   * 设备单位为：mg/dL
   **/
  const MG = 'mg/dL'

  const ded = equipmentId.value
  // const oper = oper.value

  parseData.call(this, a)

  function filterData(src: any, startStr: any, endStr: any) {
    if (src.indexOf(startStr) !== -1) {
      const start = src.indexOf(startStr)
      const end = src.indexOf(endStr, startStr) + 2
      src = src.replace(src.substring(start, end), '')
    }
    return src
  }
  /**
   * 过滤可能含有的其他数据
   */
  function filterAllData() {
    console.log('filterAllData')

    // 过滤掉上次测量结果的数据
    bleData = filterData(bleData, LAST_TIME_MEASURE_STATE_PRE, END_7D)
    // 过滤掉请插入试纸的信息
    bleData = filterData(bleData, INSERT_GLU_SENSOR_PRE, END_7D)
    bleData = filterData(bleData, INSERT_KET_SENSOR_PRE, END_7D)
    bleData = filterData(bleData, INSERT_UA_SENSOR_PRE, END_7D)
    // 过滤掉等待加血的信息
    bleData = filterData(bleData, WAITING_TO_ADD_BLOOD_GLU_PRE, END_7D)
    bleData = filterData(bleData, WAITING_TO_ADD_BLOOD_KET_PRE, END_7D)
    bleData = filterData(bleData, WAITING_TO_ADD_BLOOD_UA_PRE, END_7D)
    // 过滤掉完成加血的信息
    bleData = filterData(bleData, COMPLETED_TO_ADD_BLOOD_GLU_PRE, END_7D)
    bleData = filterData(bleData, COMPLETED_TO_ADD_BLOOD_KET_PRE, END_7D)
    bleData = filterData(bleData, COMPLETED_TO_ADD_BLOOD_UA_PRE, END_7D)
    // 过滤掉测量异常报警的信息
    bleData = filterData(bleData, ERROR_ALARM_PRE, END_7D)
  }

  function subStringData(src: any, startStr: any, endStr: any) {
    console.log('subStringData')
    if (src.indexOf(startStr) !== -1) {
      const start = src.indexOf(startStr)
      const end = src.indexOf(endStr, start) + 2
      src = src.substring(start, end)
    }
    return src
  }

  function getEndWith7D() {
    return bleData.substring(bleData.length - 2, bleData.length)
  }

  function parseSN(data: any) {
    // bleData += data;
    const endWith = getEndWith7D()
    const container = bleData.indexOf(SN_PRE)
    if (bleData.indexOf(SN_PRE) != -1 && endWith == END_7D && bleData.length > 42) {
      // 过滤掉可能夹杂有的其他数据
      filterAllData()
      // 提取出S/N串号的信息
      bleData = subStringData(bleData, SN_PRE, END_7D)
      console.log(bleData)
      const len = bleData.length
      if (len < 42) {
        return
      }
      let result = bleData.substring(len - 42, len - 10)
      console.log(result)
      result = result.substring(result.length - 26)
      console.log(result)
      const halfLength = result.length / 2
      console.log(halfLength)
      currSn = ''
      let hexChar = ''
      for (let i = 0; i < halfLength; i++) {
        hexChar = String.fromCharCode(parseInt(result.substring(2 * i, 2 * i + 2), 16))
        currSn = currSn + hexChar
      }
      bleData = ''

      console.log('sn', currSn)

      console.log(currSn, deviceNo.value)
      if (currSn && !deviceNo.value) {
        bindEquipment({
          userId: JSON.parse(uni.getStorageSync('userInfo')).userId,
          deviceNo: equipmentId.value,
          deviceName: '微策三合一分析仪',
          deviceType: 'WEICE_ANALYSER',
          idCode: currSn
        })
          .then(() => {
            //
          })
          .catch(() => {
            connected.value = false
            uni.showToast({
              title: '该设备已被其他设备绑定',
              icon: 'none',
              duration: 1000
            })
            setTimeout(() => {
              uni.redirectTo({
                url: '/module/src/pages/myEquipment/index'
              })
            }, 1000)
          })
      }

      if (oper.value == 'getSn') {
        console.log('获取到sn 跳出')
        return
      }

      let buffer = new ArrayBuffer(1)
      const buf = '7B01100120AA55000002010D087D'
      buffer = string2buffer(buf)

      //接收到sn串号 发送单位
      wx.writeBLECharacteristicValue({
        //向蓝牙设备写入数据
        deviceId: ded,
        serviceId: '0003CDD0-0000-1000-8000-00805F9B0131', //服务id 可以写死
        characteristicId: '0003CDD2-0000-1000-8000-00805F9B0131', //监控特征值id
        value: buffer,
        success: () => {
          console.log('发送单位成功')
        },
        fail: () => {
          console.log('发送单位失败')
        }
      })
    } else {
      console.log('error : ', bleData)
    }
  }

  function parseUnit(data: any) {
    // bleData += data;
    const endWith = getEndWith7D()
    if (bleData.indexOf(UNIT_PRE) != -1 && endWith == END_7D && bleData.length >= 30) {
      // 过滤掉可能夹杂有的其他数据
      filterAllData()
      // 提取设备测量单位的信息
      bleData = subStringData(bleData, UNIT_PRE, END_7D)
      const length = bleData.length
      const temp: any = bleData.substring(length - 12, length - 10)

      bleData = ''
      currUnit = MMOL
      if (!isEmpty(temp) && (temp == 11 || temp == 22)) {
        if (temp == 11) {
          currUnit = MG
        } else {
          currUnit = MMOL
        }
      }
      console.log(currUnit)

      //接收到单位串号 发送时间
      const date = new Date()
      let year = date.getFullYear()
      year = parseInt(year.toString().substr(2, 2))
      const month = date.getMonth() + 1
      const day = date.getDate()
      const hour = date.getHours() < 10 ? '0' + date.getHours() : date.getHours()
      const minute = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()
      const second = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()

      const time =
        convert(year.toString(16).toUpperCase()) +
        '' +
        convert(month.toString(16).toUpperCase()) +
        '' +
        convert(day.toString(16).toUpperCase()) +
        '' +
        convert(hour.toString(16).toUpperCase()) +
        '' +
        convert(minute.toString(16).toUpperCase()) +
        '' +
        convert(second.toString(16).toUpperCase())
      const arr = [
        0x01,
        0x10,
        0x01,
        0x20,
        0x44,
        0x66,
        0x00,
        0x06,
        year,
        month,
        day,
        hour,
        minute,
        second
      ]
      const crc = CRC.ToCRC16(arr)
      const timeStart = '7B0110012044660006'
      const timeEnd = '7D'
      console.log('crc ', crc)
      console.log('crc0 ', convert(crc.charAt(0)))
      console.log('crc1 ', convert(crc.charAt(1)))
      console.log('crc2 ', convert(crc.charAt(2)))
      console.log('crc3 ', convert(crc.charAt(3)))
      console.log(time)
      const hex =
        timeStart +
        time +
        convert(crc.charAt(2)) +
        '' +
        convert(crc.charAt(3)) +
        '' +
        convert(crc.charAt(0)) +
        '' +
        convert(crc.charAt(1)) +
        '' +
        timeEnd
      console.log('发送时间', hex)

      let buffer = new ArrayBuffer(1)
      buffer = string2buffer(hex)

      wx.writeBLECharacteristicValue({
        //向蓝牙设备写入数据
        deviceId: ded,
        serviceId: '0003CDD0-0000-1000-8000-00805F9B0131', //服务id 可以写死
        characteristicId: '0003CDD2-0000-1000-8000-00805F9B0131', //监控特征值id
        value: buffer,
        success: (res) => {
          console.log('设置时间成功', res)
        },
        fail: (res) => {
          console.log('设置时间失败')
        }
      })
    }
  }

  function parseTime(data) {
    console.log('parseTime: ', data)
    if (isEmpty(data)) {
      return
    }
    // bleData += data;
    const endWith = getEndWith7D()

    if (bleData.indexOf(SET_TIME_SUCCESS) != -1 && endWith == END_7D && bleData.length >= 30) {
      // 过滤掉可能夹杂有的其他数据
      filterAllData()
      // 提取设备测量单位的信息
      bleData = subStringData(bleData, SET_TIME_SUCCESS, END_7D)
      const length = bleData.length
      const temp: any = bleData.substring(length - 12, length - 10)
      if (isEmpty(temp)) {
        return
      }
      bleData = ''
      if (temp == 11) {
        //callback.setTimeSuccess();
        //my.alert({ content: 'setTimeSuccess' });

        if (oper.value == 'getHis') {
          let buffer = new ArrayBuffer(1)
          const buf = '7B01100120DD550000030A060C7D'
          buffer = string2buffer(buf)

          //时间设置成功，发送历史记录命令
          wx.writeBLECharacteristicValue({
            //向蓝牙设备写入数据
            deviceId: ded,
            serviceId: '0003CDD0-0000-1000-8000-00805F9B0131', //服务id 可以写死
            characteristicId: '0003CDD2-0000-1000-8000-00805F9B0131', //监控特征值id
            value: buffer,
            success: (res) => {
              console.log('发送准备试纸条成功')
            },
            fail: (res) => {
              clval.value = '获取历史数据失败'
            }
          })
        } else {
          //实时测量
          let buffer = new ArrayBuffer(1)
          const buf = '7B0110012012550000000507087D'
          buffer = string2buffer(buf)

          //时间设置成功，发送准备试纸条
          wx.writeBLECharacteristicValue({
            //向蓝牙设备写入数据
            deviceId: ded,
            serviceId: '0003CDD0-0000-1000-8000-00805F9B0131', //服务id 可以写死
            characteristicId: '0003CDD2-0000-1000-8000-00805F9B0131', //监控特征值id
            value: buffer,
            success: (res) => {
              console.log('发送准备试纸条成功')
            },
            fail: (res) => {
              clval.value = '准备试纸条失败'
            }
          })
          console.log('000000000000')
          clval.value = '设备已连接，选择测量人'
        }
      } else {
        //callback.setTimeFailure();
        //my.alert({ content: '设置同步时间失败' });
        clval.value = '获取蓝牙设备失败'
      }
    }
  }

  /**
   * 提取测量时间
   * @param data
   */
  function parseMeasureTime(data) {
    if (isEmpty(data)) {
      return Date.now()
    }
    const length = data.length

    const year = parseInt(data.substring(0, 2), 16) + 2000
    const month = parseInt(data.substring(2, 4), 16)
    const day = parseInt(data.substring(4, 6), 16)
    const hour = parseInt(data.substring(6, 8), 16)
    const minute = parseInt(data.substring(8, 10), 16)
    let flag
    length >= 12 ? (flag = true) : (flag = false)
    const second = flag ? parseInt(data.substring(10, 12), 16) : 0
    let time =
      year +
      '-' +
      p(month) +
      '-' +
      p(day) +
      ' ' +
      p(hour) +
      ':' +
      p(minute) +
      (flag ? ':' + p(second) : '')

    pmt = time

    console.log('parseMeasureTime : ', pmt)
    let milliseconds = 0
    //            if (flag) {
    //                 time = '2018-07-09 14:13:11';
    time = time.replace(new RegExp('-', 'gm'), '/')
    milliseconds = new Date(time).getTime() //得到毫秒数
    // return milliseconds;

    return pmt
  }
  //创建补0函数
  function p(s) {
    return s < 10 ? '0' + s : s
  }
  /**
   * 提取血糖值
   * @param highByte
   * @param lowByte
   * @param unit
   */
  function parseGlucoseValue(highByte, lowByte, unit) {
    //my.hideLoading({});
    if (isEmpty(highByte) || isEmpty(lowByte)) {
      return 0
    }
    // 血糖值计算(高位乘以100后，加上低位的值即为血糖值)
    //            const high = Integer.valueOf(highByte, 16);
    //            const down = Integer.valueOf(lowByte, 16);
    //            const result = (high * 100) + down;
    const high = parseInt(highByte, 16)
    const down = parseInt(lowByte, 16)
    const result = high * 100 + down

    let glucoseValue: any = result

    if (unit == MMOL) {
      const value = result / 10
      glucoseValue = value.toFixed(1)
    }
    return glucoseValue
  }
  //计算血酮
  function parseKetValue(highByte, lowByte) {
    if (isEmpty(highByte) || isEmpty(lowByte)) {
      return 0
    }
    const high = parseInt(highByte, 16)
    const down = parseInt(lowByte, 16)
    const result = high * 100 + down
    const value = result / 100
    const ketValue = value.toFixed(1)
    return ketValue
  }

  //计算尿酸
  function parseUaValue(highByte, lowByte) {
    if (isEmpty(highByte) || isEmpty(lowByte)) {
      return 0
    }
    const high = parseInt(highByte, 16)
    const down = parseInt(lowByte, 16)
    const result = high * 100 + down
    return result
  }
  function parseHistory(data) {
    // bleData += data;
    const list = new Array()
    const endWith = getEndWith7D()
    if (
      bleData.indexOf(HISTORY_PRE) != -1 &&
      bleData.indexOf(HISTORY_END_PRE) != -1 &&
      endWith == END_7D
    ) {
      // 过滤掉可能夹杂有的其他数据
      filterAllData()
      const temps = bleData.split(END_7D)
      if (temps == null || temps.length == 0) {
        return
      }
      const length = temps.length
      console.log(temps)
      for (let i = 0; i < length; i++) {
        const tempLength = temps[i].length
        if (tempLength > 40) {
          // 11/55/77为血液 22/66/88为质控液
          let valueType: any = temps[i].substring(tempLength - 10, tempLength - 8)
          // if (valueType == 22 || valueType == 66 || valueType == 88) {
          //   continue;
          // }

          if (valueType == 22) {
            console.log('CTRL')
            valueType = 'CTRL'
            const temp = temps[i].substring(tempLength - 26, tempLength - 12)
            const measureTime = parseMeasureTime(temp)

            if (temp.length == 14) {
              const historicalData: any = {
                measureTime,
                currSn,
                currUnit,
                valueType
              }
              historicalData.valueType = 'BLOOD'
              historicalData.value = parseGlucoseValue(
                temp.substring(10, 12),
                temp.substring(12, 14),
                currUnit
              )

              list.push(historicalData)
            }
          } else if (valueType == 66) {
            valueType = 'CTRL_KET'
          } else if (valueType == 88) {
            valueType = 'CTRL_UA'
          } else {
            const temp = temps[i].substring(tempLength - 26, tempLength - 12)
            const measureTime = parseMeasureTime(temp)

            if (temp.length == 14) {
              const historicalData: any = {
                measureTime,
                currSn,
                currUnit,
                valueType
              }
              if (valueType == 11) {
                historicalData.valueType = 'BLOOD'
                historicalData.value = parseGlucoseValue(
                  temp.substring(10, 12),
                  temp.substring(12, 14),
                  currUnit
                )
              } else if (valueType == 55) {
                historicalData.valueType = 'BLOOD_KET'
                historicalData.value = parseKetValue(temp.substring(10, 12), temp.substring(12, 14))
                historicalData.currUnit = 'mmol/L'
              } else if (valueType == 77) {
                historicalData.valueType = 'BLOOD_UA'
                historicalData.value = parseUaValue(temp.substring(10, 12), temp.substring(12, 14))
                historicalData.currUnit = 'μmol/L'
              }
              list.push(historicalData)
            }
          }
        }
      }
      bleData = ''

      history = list
      clval.value = ' '
      // now = false;
      console.log(list)

      console.log('parseHistory:  ' + JSON.stringify(list))
    } else if (bleData.indexOf(HISTORY_END_PRE) != -1 && endWith == END_7D) {
      //暂无历史数据
      bleData = ''
    }
  }

  function parseRealTimeMeasureData(data) {
    // bleData += data;
    console.log('bleData : ' + bleData)

    // 打印提取的蓝牙信息
    const pa = /7b0120011012660005(.{2})/g
    let res: any = ''
    while ((res = pa.exec(bleData)) !== null) {
      console.log('statueCode----', res[1])
    }

    // 上次测量结果状态提示和过滤
    filterRealTimeMeasureToast(LAST_TIME_MEASURE_STATE_PRE, END_7D)
    // 已插入试纸提示和过滤
    filterRealTimeMeasureToast(INSERT_GLU_SENSOR_PRE, END_7D)
    filterRealTimeMeasureToast(INSERT_KET_SENSOR_PRE, END_7D)
    filterRealTimeMeasureToast(INSERT_UA_SENSOR_PRE, END_7D)
    // 等待加血提示和过滤
    filterRealTimeMeasureToast(WAITING_TO_ADD_BLOOD_GLU_PRE, END_7D)
    filterRealTimeMeasureToast(WAITING_TO_ADD_BLOOD_KET_PRE, END_7D)
    filterRealTimeMeasureToast(WAITING_TO_ADD_BLOOD_UA_PRE, END_7D)
    // 完成加血提示和过滤
    filterRealTimeMeasureToast(COMPLETED_TO_ADD_BLOOD_GLU_PRE, END_7D)
    filterRealTimeMeasureToast(COMPLETED_TO_ADD_BLOOD_KET_PRE, END_7D)
    filterRealTimeMeasureToast(COMPLETED_TO_ADD_BLOOD_UA_PRE, END_7D)
    // 测量异常报警提示和过滤
    filterRealTimeMeasureToast(ERROR_ALARM_PRE, END_7D)

    const endWith = getEndWith7D()
    // bleData.in
    //解析测量值和测量时间
    const MEASURE_RESULT_VALUE_PRE_ARR = [
      MEASURE_RESULT_VALUE_GLU_PRE,
      MEASURE_RESULT_VALUE_KET_PRE,
      MEASURE_RESULT_VALUE_UA_PRE
    ]
    const filterPres = MEASURE_RESULT_VALUE_PRE_ARR.filter((item) => {
      return bleData.indexOf(item) != -1
    })
    const MEASURE_RESULT_VALUE_PRE = filterPres[0]
    if (
      MEASURE_RESULT_VALUE_PRE &&
      bleData.indexOf(MEASURE_RESULT_TIME_PRE) != -1 &&
      endWith == END_7D
    ) {
      const startValue = bleData.indexOf(MEASURE_RESULT_VALUE_PRE)
      const endValue = bleData.indexOf(END_7D, startValue) + 2

      const startTime = bleData.indexOf(MEASURE_RESULT_TIME_PRE)
      const endTime = bleData.indexOf(END_7D, startTime) + 2

      const dataSrcValue = bleData.substring(startValue, endValue)
      const dataSrcTime = bleData.substring(startTime, endTime)

      const lengthValue = dataSrcValue.length
      const lengthTime = dataSrcTime.length

      if (lengthValue > 20 && lengthTime > 22) {
        const tempValue = dataSrcValue.substring(lengthValue - 20, lengthValue - 10)
        const tempTime = dataSrcTime.substring(lengthTime - 22, lengthTime - 10)

        const measureTime = parseMeasureTime(tempTime)

        if (!isEmpty(tempValue) && !isEmpty(tempTime)) {
          const stateCode = tempValue.substring(0, 2)
          const sampleCode = tempValue.substring(6, 8) //样本类型
          if (sampleCode == '33') {
            return //样本错误
          }

          let valueType //数据类型
          console.log('测量标识======', stateCode)
          if (stateCode == '44') {
            //血糖
            //11为血液 22为质控
            if (sampleCode == '11') {
              valueType = 'BLOOD'
            } else if (sampleCode == '22') {
              valueType = 'CTRL'
              controlSolution = 1
            }

            const value = parseGlucoseValue(
              tempValue.substring(2, 4),
              tempValue.substring(4, 6),
              currUnit
            )
            measureData.value = {
              measureTime,
              value,
              currSn,
              currUnit,
              valueType
            }
            clval.value = '测量完成-血糖'
            console.log('血糖实时 : ', measureData)
            //bleData = "";
            //callback.realTimeMeasureData(glucose);
          } else if (stateCode == '99') {
            //血酮 单位固定为mmol/L
            //55为血液 66为质控
            if (sampleCode == '11') {
              valueType = 'BLOOD_KET'
            } else if (sampleCode == '66') {
              valueType = 'CTRL_KET'
              controlSolution = 1
            }
            const value = parseKetValue(tempValue.substring(2, 4), tempValue.substring(4, 6))
            measureData.value = {
              measureTime,
              value,
              currSn,
              currUnit: 'mmol/L',
              valueType
            }
            clval.value = '测量完成-血酮'
            console.log('血酮实时 : ', measureData.value)
          } else if (stateCode == 'dd') {
            //尿酸 单位固定为μmol/L
            //77为血液 88为质控
            if (sampleCode == '77') {
              valueType = 'BLOOD_UA'
            } else if (sampleCode == '88') {
              valueType = 'CTRL_UA'
              controlSolution = 1
            }
            const value = parseUaValue(tempValue.substring(2, 4), tempValue.substring(4, 6))
            measureData.value = {
              measureTime,
              value,
              currSn,
              currUnit: 'μmol/L',
              valueType
            }
            clval.value = '测量完成-尿酸'
            console.log('尿酸实时 : ', measureData.value)
          }

          const data = {
            ...measureData.value,
            name: 'analysis',
            measureEmpi: measureEmpi.value,
            deviceId: equipmentId.value
          }
          const vo = encodeURIComponent(JSON.stringify(data))
          uni.redirectTo({
            url: `/module/src/pages/myEquipment/result?data=${vo}`
          })
        }
      }
    }
  }

  function parseData(data) {
    console.log('data: ', data)

    bleData += data

    console.log(new Date(), bleData)

    if (bleData.indexOf(SN_PRE) != -1) {
      //                解析SN
      parseSN(bleData)
    } else if (bleData.indexOf(UNIT_PRE) != -1) {
      //               解析测量单位
      parseUnit(bleData)
    } else if (bleData.indexOf(SET_TIME_SUCCESS) != -1) {
      //                // 设置蓝牙设备的时间
      parseTime(bleData)
    } else if (bleData.indexOf(HISTORY_PRE) != -1 && bleData.indexOf(HISTORY_END_PRE) != -1) {
      //                历史记录
      parseHistory(bleData)
    } else if (bleData.indexOf(HISTORY_END_PRE) != -1) {
      //历史记录
      parseHistory(bleData)
    } else if (bleData.indexOf(POWER_OFF) != -1) {
      //关闭蓝牙模块
      wx.closeBluetoothAdapter()

      gloableDevices.value = []
    } else {
      // 默认也解析实时测量数据
      parseRealTimeMeasureData(bleData)
    }
  }

  function filterRealTimeMeasureToast(startStr, endStr) {
    if (bleData.indexOf(startStr) != -1 && bleData.indexOf(endStr) != -1) {
      console.log('filterRealTimeMeasureToast if')
      const start = bleData.indexOf(startStr)
      const end = bleData.indexOf(endStr, start) + 2

      const dataSrc = bleData.substring(start, end)
      const length = dataSrc.length
      if (length > 20) {
        bleData = bleData.replace(dataSrc, '')

        const temp = dataSrc.substring(length - 20, length - 10)

        //my.alert({ content: 'temp:  ' + temp });

        if (!isEmpty(temp)) {
          const stateCode = temp.substring(0, 2)
          const toastType = 0
          console.log(stateCode)

          //上次测量结果状态提示
          if (stateCode == 'unToast_10') {
            //callback.realTimeMeasureToast("上次测量的记录");
            clval.value = '上次测量结果'
            console.log('上次测量的记录')
            //my.alert({ content: 'realTimeMeasureToast:  ' + '上次测量的记录' });
          } else if (stateCode == '11' || stateCode == '66' || stateCode == 'aa') {
            // callback.realTimeMeasureToast("已插入试纸");
            clval.value = '已插入试纸'
            // history = false;
            // now = true;
            console.log('已插入试纸')
          } else if (stateCode == '22' || stateCode == '77' || stateCode == 'bb') {
            //callback.realTimeMeasureToast("等待加血");
            clval.value = '等待加血...'
            console.log('等待加血')
          } else if (stateCode == '33' || stateCode == '88' || stateCode == 'cc') {
            //callback.realTimeMeasureToast("完成加血");
            clval.value = '加血完成，请稍后...'
            console.log('完成加血')
          } else if (stateCode == 'ee' || stateCode == 'ff') {
            console.log('已插条/已读取结束')
          } else if (stateCode == '55') {
            //callback.realTimeMeasureToast("测量异常");
            clval.value = '测量异常,请重试'
            console.log('测量异常')
            //关闭蓝牙模块
            wx.closeBluetoothAdapter()
          }
        }
      }
    }
  }

  //判断字符是否为空的方法
  function isEmpty(obj) {
    if (typeof obj == 'undefined' || obj == null || obj == '') {
      return true
    } else {
      return false
    }
  }
}

function inArray(arr: any, key: any, val: any) {
  for (let i = 0; i < arr.length; i++) {
    if (arr[i][key] === val) {
      return i
    }
  }
  return -1
}

function convert(time: any) {
  if (time.length < 2) {
    time = '0' + time
  }
  return time
}

const CRC: any = {}

CRC._auchCRCHi = [
  0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40,
  0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41,
  0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41,
  0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40,
  0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41,
  0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40,
  0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40,
  0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41,
  0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41,
  0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40,
  0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40,
  0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41,
  0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40,
  0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41,
  0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41,
  0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40
]
CRC._auchCRCLo = [
  0x00, 0xc0, 0xc1, 0x01, 0xc3, 0x03, 0x02, 0xc2, 0xc6, 0x06, 0x07, 0xc7, 0x05, 0xc5, 0xc4, 0x04,
  0xcc, 0x0c, 0x0d, 0xcd, 0x0f, 0xcf, 0xce, 0x0e, 0x0a, 0xca, 0xcb, 0x0b, 0xc9, 0x09, 0x08, 0xc8,
  0xd8, 0x18, 0x19, 0xd9, 0x1b, 0xdb, 0xda, 0x1a, 0x1e, 0xde, 0xdf, 0x1f, 0xdd, 0x1d, 0x1c, 0xdc,
  0x14, 0xd4, 0xd5, 0x15, 0xd7, 0x17, 0x16, 0xd6, 0xd2, 0x12, 0x13, 0xd3, 0x11, 0xd1, 0xd0, 0x10,
  0xf0, 0x30, 0x31, 0xf1, 0x33, 0xf3, 0xf2, 0x32, 0x36, 0xf6, 0xf7, 0x37, 0xf5, 0x35, 0x34, 0xf4,
  0x3c, 0xfc, 0xfd, 0x3d, 0xff, 0x3f, 0x3e, 0xfe, 0xfa, 0x3a, 0x3b, 0xfb, 0x39, 0xf9, 0xf8, 0x38,
  0x28, 0xe8, 0xe9, 0x29, 0xeb, 0x2b, 0x2a, 0xea, 0xee, 0x2e, 0x2f, 0xef, 0x2d, 0xed, 0xec, 0x2c,
  0xe4, 0x24, 0x25, 0xe5, 0x27, 0xe7, 0xe6, 0x26, 0x22, 0xe2, 0xe3, 0x23, 0xe1, 0x21, 0x20, 0xe0,
  0xa0, 0x60, 0x61, 0xa1, 0x63, 0xa3, 0xa2, 0x62, 0x66, 0xa6, 0xa7, 0x67, 0xa5, 0x65, 0x64, 0xa4,
  0x6c, 0xac, 0xad, 0x6d, 0xaf, 0x6f, 0x6e, 0xae, 0xaa, 0x6a, 0x6b, 0xab, 0x69, 0xa9, 0xa8, 0x68,
  0x78, 0xb8, 0xb9, 0x79, 0xbb, 0x7b, 0x7a, 0xba, 0xbe, 0x7e, 0x7f, 0xbf, 0x7d, 0xbd, 0xbc, 0x7c,
  0xb4, 0x74, 0x75, 0xb5, 0x77, 0xb7, 0xb6, 0x76, 0x72, 0xb2, 0xb3, 0x73, 0xb1, 0x71, 0x70, 0xb0,
  0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54,
  0x9c, 0x5c, 0x5d, 0x9d, 0x5f, 0x9f, 0x9e, 0x5e, 0x5a, 0x9a, 0x9b, 0x5b, 0x99, 0x59, 0x58, 0x98,
  0x88, 0x48, 0x49, 0x89, 0x4b, 0x8b, 0x8a, 0x4a, 0x4e, 0x8e, 0x8f, 0x4f, 0x8d, 0x4d, 0x4c, 0x8c,
  0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80, 0x40
]

CRC.CRC16 = function (buffer) {
  // var hi = 0xff;
  // var lo = 0xff;
  // for (var i = 0; i < buffer.length; i++) {
  //   var idx = hi ^ buffer[i];
  //   hi = (lo ^ CRC._auchCRCHi[idx]);
  //   lo = CRC._auchCRCLo[idx];
  // }
  // return CRC.padLeft((hi << 8 | lo).toString(16).toUpperCase(), 4, '0');
  var hi = 0xff
  var lo = 0xff
  for (var i = 0; i < buffer.length; i++) {
    //                var idx = hi ^ buffer[i];
    //                hi = (lo ^ CRC._auchCRCHi[idx]);
    //                lo = CRC._auchCRCLo[idx];
    var idx = lo ^ buffer[i]
    lo = hi ^ CRC._auchCRCHi[idx]
    hi = CRC._auchCRCLo[idx]
  }
  return CRC.padLeft(((hi << 8) | lo).toString(16).toUpperCase(), 4, '0')
}

CRC.isArray = function (arr) {
  return Object.prototype.toString.call(arr) === '[object Array]'
}

CRC.ToCRC16 = function (str) {
  return CRC.CRC16(CRC.isArray(str) ? str : CRC.strToByte(str))
}

CRC.ToModbusCRC16 = function (str) {
  return CRC.CRC16(CRC.isArray(str) ? str : CRC.strToHex(str))
}

CRC.strToByte = function (str) {
  var tmp = str.split(''),
    arr = []
  for (var i = 0, c = tmp.length; i < c; i++) {
    var j = encodeURI(tmp[i])
    if (j.length == 1) {
      arr.push(j.charCodeAt())
    } else {
      var b = j.split('%')
      for (var m = 1; m < b.length; m++) {
        arr.push(parseInt('0x' + b[m]))
      }
    }
  }
  return arr
}

CRC.convertChinese = function (str) {
  var tmp = str.split(''),
    arr = []
  for (var i = 0, c = tmp.length; i < c; i++) {
    var s = tmp[i].charCodeAt()
    if (s <= 0 || s >= 127) {
      arr.push(s.toString(16))
    } else {
      arr.push(tmp[i])
    }
  }
  return arr
}

CRC.filterChinese = function (str) {
  var tmp = str.split(''),
    arr = []
  for (var i = 0, c = tmp.length; i < c; i++) {
    var s = tmp[i].charCodeAt()
    if (s > 0 && s < 127) {
      arr.push(tmp[i])
    }
  }
  return arr
}

CRC.strToHex = function (hex, isFilterChinese) {
  hex = isFilterChinese ? CRC.filterChinese(hex).join('') : CRC.convertChinese(hex).join('')

  //清除所有空格
  hex = hex.replace(/\s/g, '')
  //若字符个数为奇数，补一个空格
  hex += hex.length % 2 != 0 ? ' ' : ''

  var c = hex.length / 2,
    arr = []
  for (var i = 0; i < c; i++) {
    arr.push(parseInt(hex.substr(i * 2, 2), 16))
  }
  return arr
}

CRC.padLeft = function (s, w, pc) {
  if (pc == undefined) {
    pc = '0'
  }
  for (var i = 0, c = w - s.length; i < c; i++) {
    s = pc + s
  }
  return s
}
</script>
<style lang="scss" scoped>
.wrap {
  position: relative;
  min-height: 100vh;
  padding: 32rpx;
  overflow: hidden;
}

.not-bind {
  display: flex;
  flex-direction: column;

  .equipment-box {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 364rpx;
    padding-bottom: 32rpx;
    background: #fff;
    border-radius: 24rpx;
  }

  .bing-sn {
    margin-top: 16rpx;
    font-size: 32rpx;
    font-weight: 700;
    color: #000;
  }

  .bind-box {
    width: 100%;
    height: 88rpx;
    line-height: 88rpx;
    text-align: center;
    background-color: #00d1b6;
    border-radius: 44rpx;

    .bind-text {
      font-size: 32rpx;
      font-weight: 700;
      color: #fff;
    }
  }
}

.equipment-unbind {
  position: absolute;
  top: 12rpx;
  right: 12rpx;
  z-index: 100;
  width: 144rpx;
  height: 50rpx;
  text-align: center;
  border: 1rpx solid #e5e6eb;
  border-radius: 28rpx;

  .unbind-text {
    display: inline-block;
    font-size: 24rpx;
    font-weight: 700;
    line-height: 50rpx;
    color: #222;
  }
}

.device_item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 108rpx;
  border-bottom: 1px solid #e5e6eb;

  .device_name {
    font-size: 32rpx;
    font-weight: 700;
    color: #222;
  }
}

.equipment-image {
  width: 300rpx;
  height: 300rpx;
}

.equipment-title {
  display: flex;
  margin-top: 50rpx;
  margin-bottom: 24rpx;

  .equipment-text {
    margin-right: 8rpx;
    font-size: 40rpx;
    font-weight: 700;
    color: #1d2129;
  }
}

.equiment-list {
  width: 100%;
  height: calc(100vh - 550rpx);
  padding: 0 32rpx 32rpx;
  background-color: #fff;
  border-radius: 16rpx;

  .equiment-scroll {
    height: 100%;
  }
}

.patient-title {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 50rpx;
  margin-top: 48rpx;
  margin-bottom: 24rpx;

  .bind-desc {
    font-size: 36rpx;
    font-weight: 700;
    color: #1d2129;
  }
}

.patient-item {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  height: 108rpx;
  padding: 0 32rpx;
  background-color: #fff;
  border-radius: 16rpx;

  .patient-name {
    font-size: 30rpx;
    font-weight: 700;
    color: #222;
  }

  .patient-right {
    display: flex;
    align-items: center;
    height: 100%;
  }

  .patient-select-image {
    width: 40rpx;
    height: 40rpx;
  }

  .patient-value {
    margin-right: 8rpx;
    font-size: 30rpx;
    font-weight: 400;
    color: #222;
  }
}

.u-popup {
  .title {
    height: 108rpx;
    font-size: 32rpx;
    font-weight: 700;
    line-height: 108rpx;
    color: #222;
    text-align: center;
    border-bottom: 1rpx solid #e5e6eb;
  }

  .lists {
    max-height: 800rpx;
    padding: 32rpx;
    overflow-y: scroll;

    .item {
      position: relative;
      display: flex;
      align-items: center;
      width: 100%;
      height: 96rpx;
      padding-left: 24rpx;
      margin-bottom: 24rpx;
      background: #fafafa;
      border-radius: 16rpx;

      .name {
        font-size: 32rpx;
        font-weight: 700;
        color: #222;
      }

      .exam-info {
        display: flex;
        align-items: center;
        justify-content: center;
        width: 142rpx;
        height: 48rpx;
        margin-left: 32rpx;
        background: #fff;
        border: 1rpx solid #e5e6eb;
        border-radius: 4rpx;

        .text {
          font-size: 24rpx;
          font-weight: 400;
          color: #666;
        }
      }

      .select_img {
        position: absolute;
        top: 0;
        right: 0;
        width: 45rpx;
        height: 40rpx;
      }
    }
  }
}

.manual-box {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 88rpx;
  margin-top: 72rpx;
}

.confirm-box {
  position: absolute;
  bottom: 0;
  left: 0;
  z-index: 10;
  width: 100%;
  height: 206rpx;
  padding: 24rpx 32rpx;
  background: #fff;
}

.reuseConnect {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 88rpx;
  margin-top: 72rpx;
}

.matching-box {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  height: 88rpx;
  margin-top: 72rpx;
}

.matching-item {
  display: block;
  width: 48%;
  height: 88rpx;
  font-size: 32rpx;
  font-weight: 700;
  line-height: 88rpx;
  color: #fff;
  text-align: center;
  background: #00d1b6;
  border-radius: 44rpx;
}

.patient-confirm {
  display: block;
  width: 686rpx;
  height: 88rpx;
  font-size: 32rpx;
  font-weight: 700;
  line-height: 88rpx;
  color: #fff;
  text-align: center;
  background: #00d1b6;
  border-radius: 44rpx;
}

.item-active {
  background: rgb(0 209 182 / 10%);
  border: 1rpx solid #00d1b6;
}
</style>
